<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2024/4/10
 * Time: 12:01
 */

namespace plugin\admin\app\logic\material;


use app\common\lib\Common;
use app\common\lib\RedisQueue;
use app\common\lib\TencentCos;
use app\exception\IndexException;
use JamesHeinrich\GetID3\GetID3;
use plugin\admin\app\logic\BaseLogic;
use plugin\admin\app\model\material\MaterialCatgoryModel;
use plugin\admin\app\model\material\MaterialDataModel;
use plugin\admin\app\model\material\MaterialDataCosModel;
use support\Request;
use support\Response;
use support\Log;

class MaterialLogic extends BaseLogic
{
    protected static $instance;

    public function __construct()
    {
        $this->model = new MaterialDataModel();
    }

    public static function getInstance()
    {
        //        if(is_object(self::$instance)){
//            return self::$instance;
//        }

        return new self();
    }

    public function select(Request $request): Response
    {
        $field = $request->input('field');
        if($field==false){
            $request->inputSet('field','created_at');
            $request->inputSet('order','desc');
        }
        if(!empty($request->input('ids'))){
            $request->inputSet('id',['in',$request->input('ids')]);
        }

        $request->inputSet('isdel','0');
        return parent::select($request);
    }

    protected function formatNormal($items, $total): Response
    {

        $material_data_id_arr = [];
        $categoryMap = $this->getListMapById(MaterialCatgoryModel::getInstance(),$items,'catid','id');
        foreach($items as $k=>&$val){
            if(\request()->input('fileter_empty') && empty($val['heigh_video_tts']) && empty($val['normal_video_tts'])){
                unset($items[$k]);
            }

            $val['catname'] = isset($categoryMap[$val['catid']])?$categoryMap[$val['catid']]['name']:$val['catid'];
            $val['heigh_video_data'] = !empty($val['heigh_video_data']) ? json_decode($val['heigh_video_data']) : [];
            $val['normal_video_data'] = !empty($val['normal_video_data']) ? json_decode($val['normal_video_data']) : [];

            if(isset($val['material_data_id'])){
                $material_data_id_arr[] = $val['material_data_id'];
            }
        }

        if(count($material_data_id_arr) > 0){
            $m = new MaterialDataModel();
            $material_data = $m->select('id', 'name')->whereIn('id', $material_data_id_arr)->get();
            if(!empty($material_data)){
                $md_arr = [];
                foreach($material_data as $mdv){
                    $md_arr[$mdv['id']] = $mdv['name'];
                }

                foreach($items as &$iv){
                    $iv['material_data_name'] = isset($md_arr[$iv['material_data_id']]) ? $md_arr[$iv['material_data_id']] : '';
                }
            }
        }

        $items = array_values($items);
        return parent::formatNormal($items, $total);
    }

    public function insert(Request $request): Response
    {
        $videoData = $request->input('orig_heigh_video_data');
        if(!empty($videoData)){
            //获取视频长度
            $request->inputSet('orig_heigh_video_data',json_encode($videoData,256));
            $request->inputSet('heigh_video_nums',count($videoData));
        }

        $videoData2 = $request->input('orig_normal_video_data');
        if(!empty($videoData2)){
            //获取视频长度
            $request->inputSet('orig_normal_video_data',json_encode($videoData2,256));
            $request->inputSet('normal_video_nums',count($videoData2));
        }
        return parent::insert($request);
    }

    protected function doInsert(array $data)
    {
        $id = parent::doInsert($data); // TODO: Change the autogenerated stub
        if($id){
            //生成唯一的请求id
            $requestId = Common::getRequestId();

            // 队列名
            $queue = 'asyncVideoMaterial';
            // 数据，可以直接传数组，无需序列化
            $data = ['requestid' => $requestId, 'materialid' => $id];
            // 投递消息
            RedisQueue::getInstance()->sendQueue($queue, $data);
        }
        return $id;
    }

    public function update(Request $request): Response
    {
        $videoData = $request->input('orig_heigh_video_data');
        if(!empty($videoData)){
            $request->inputSet('orig_heigh_video_data',json_encode($videoData,256));
            $request->inputSet('heigh_video_nums',count($videoData));
        }

        $videoData2 = $request->input('orig_normal_video_data');
        if(!empty($videoData2)){
            $request->inputSet('orig_normal_video_data',json_encode($videoData2,256));
            $request->inputSet('normal_video_nums',count($videoData2));
        }
        $request->inputSet('queue_status',0);
        return parent::update($request);
    }

    protected function doUpdate($id, $data)
    {
        parent::doUpdate($id, $data); // TODO: Change the autogenerated stub

        $queueKey = '{redis-queue}-waitingasyncVideoMaterial';
        $redisQueues = \Webman\RedisQueue\Redis::connection()->lRange($queueKey,0,-1);
        $isHas = false;
        foreach($redisQueues as $q){
            $qData = json_decode($q, true);
            if($qData['data']['materialid']==$id){
                $isHas = true;
                break;
            }
        }
        if($isHas==false){
            //生成唯一的请求id
            $requestId = Common::getRequestId();

            // 队列名
            $queue = 'asyncVideoMaterial';
            // 数据，可以直接传数组，无需序列化
            $data = ['requestid' => $requestId, 'materialid' => $id];
            // 投递消息
            RedisQueue::getInstance()->sendQueue($queue, $data);
        }
    }

    public function delete(Request $request): Response
    {
        return parent::isDelete($request);
    }

    public function sysncmaterial(Request $request): Response
    {
        $pathData = $request->input('material_path');
        if($pathData==false){
            throw new IndexException(4020,'素材路径不能为空');
        }

        $paths = explode(',', $pathData);
        $videos = [];
        $urls = [];
        foreach($paths as $path){
            $marker = '';
            $i = 1;
            while (true){
                $result = TencentCos::getInstance()->getBucketListObject($path, $marker);

                Log::info($i . '. path:' . $path . ' marker:' . $marker, $result); // 从cos那拿回来是数据
                $i++;

                if(!empty($result['Contents'])){
                    if(!empty($result['NextMarker']) && (urldecode($result['NextMarker'])==$marker)){
                        break;
                    }

                    foreach ($result['Contents'] as $res){
                        if($res['Size']>0){
                            $url = 'https://'.$result['Location'].$res['Key'];
                            $arr = explode('/',$url);
                            $name = $arr[count($arr)-1];
                            !in_array($url,$urls) && $videos[] = ['url'=>$url,'name'=>substr($name,-14)];
                            !in_array($url,$urls) && $urls[] = $url;
                        }
                    }
                    if(!empty($result['NextMarker']) && (urldecode($result['NextMarker'])!=$marker)){
                        $marker = urldecode($result['NextMarker']);
                    }else{
                        break;
                    }
                }else{
                    break;
                }
            }
        }

        Log::info('Last. sysncAllMaterial 把 ' . $pathData . ' 的videos搞回来：', $videos);

        return $this->json(0,'ok',['videos'=>$videos]);
    }

    public function sysncAllMaterial(Request $request): Response
    {        
        $res = $request->all();

        if ($res['heigh_material_path'] != '') {

            $data = [];
            $data['material_data_id'] = $res['s_id'];
            $data['material_path'] = $res['heigh_material_path'];
            $data['catid'] = $res['catid'];
            $this->sysncAllMaterialAction($data);

        }

        if ($res['normal_material_path'] != '') {

            $data = [];
            $data['material_data_id'] = $res['s_id'];
            $data['material_path'] = $res['normal_material_path'];
            $data['catid'] = $res['catid'];
            $this->sysncAllMaterialAction($data);

        }

        return $this->json(0,'ok',[]);
    }

    protected function sysncAllMaterialAction($data)
    {
        if(!isset($data['material_data_id']) || $data['material_data_id'] < 1){
            throw new IndexException(4020,'素材ID不能为空');
        }

        $pathData = $data['material_path'];
        if($pathData==false){
            throw new IndexException(4020,'素材路径不能为空');
        }

        $paths = explode(',', $pathData);
        $videos = [];
        $urls = [];
        foreach($paths as $path){
            $marker = '';
            $i = 1;
            while (true){
                $result = TencentCos::getInstance()->getBucketListObject($path, $marker);

                Log::info($i . '. path:' . $path . ' marker:' . $marker, $result); // 从cos那拿回来是数据
                $i++;

                if(!empty($result['Contents'])){
                    if(!empty($result['NextMarker']) && (urldecode($result['NextMarker'])==$marker)){
                        break;
                    }

                    foreach ($result['Contents'] as $res) {
                        if($res['Size']>0){
                            $url = 'https://'.$result['Location'].$res['Key'];
                            $arr = explode('/',$url);
                            $name = $arr[count($arr)-1];
                            $videoid = isset($res['Owner']['ID']) ? $res['Owner']['ID'] : 0;
                            $updated_at = date('Y-m-d H:i:s', strtotime($res['LastModified']));
                            !in_array($url,$urls) && $videos[] = ['url'=>$url,'name'=>urldecode($name), 'size' => $res['Size'], 'videoid' => $videoid, 'key' => $res['Key'], 'updated_at' => $updated_at];
                            !in_array($url,$urls) && $video_data[] = ['video'=>$url,'name'=>substr($name,-14)];
                            !in_array($url,$urls) && $urls[] = $url;
                        }
                    }
                    if(!empty($result['NextMarker']) && (urldecode($result['NextMarker'])!=$marker)){
                        $marker = urldecode($result['NextMarker']);
                    }else{
                        break;
                    }
                }else{
                    break;
                }
            }
        }

        Log::info('Last. sysncAllMaterial 把 ' . $pathData . ' 的videos搞回来：', $videos);

        // 先清除素材id下的所有文件
        $cos_model = new MaterialDataCosModel();
        $cos_model->where('material_data_id', $data['material_data_id'])->delete();

        if ($videos && count($videos) > 0) {
            foreach ($videos as $v) {
                $cos_model = new MaterialDataCosModel();

                $cos_model->catid = $data['catid'];
                $cos_model->material_data_id = $data['material_data_id'];
                $cos_model->material_path = $data['material_path'];
                $cos_model->video = $v['url'];
                $cos_model->name = $v['name'];
                $cos_model->size = $v['size'];
                $cos_model->videoid = $v['videoid'];
                $cos_model->key = $v['key'];
                $cos_model->tts = '';
                $cos_model->width = '';
                $cos_model->height = '';
                $cos_model->video_scale = '';
                $cos_model->created_at = $v['updated_at'];
                $cos_model->updated_at = $v['updated_at'];

                $cos_model->save();
            }

        }

        $material_data = $this->model->where('id', $data['material_data_id'])->first();
        $u_data['queue_status'] = 0;
        if ($data['material_path'] == $material_data['heigh_material_path']) {
            $u_data['orig_heigh_video_data'] = json_encode($video_data);
            $u_data['heigh_video_nums'] = count($video_data);
        }
        if ($data['material_path'] == $material_data['normal_material_path']) {
            $u_data['orig_normal_video_data'] = json_encode($video_data);
            $u_data['normal_video_nums'] = count($video_data);
        }
        $this->model->where('id', $data['material_data_id'])->update($u_data);

        $queueKey = '{redis-queue}-waitingasyncVideoMaterial';
        $redisQueues = \Webman\RedisQueue\Redis::connection()->lRange($queueKey,0,-1);
        $isHas = false;
        foreach($redisQueues as $q){
            $qData = json_decode($q, true);
            if($qData['data']['materialid']==$data['material_data_id']){
                $isHas = true;
                break;
            }
        }
        if($isHas==false){
            //生成唯一的请求id
            $requestId = Common::getRequestId();

            // 队列名
            $queue = 'asyncVideoMaterial';
            // 投递消息
            RedisQueue::getInstance()->sendQueue($queue, ['requestid' => $requestId, 'materialid' => $data['material_data_id']]);
        }
    }

    public function selectcos(Request $request): Response
    {
        $this->model = new MaterialDataCosModel();
        $field = $request->input('field');
        if($field==false){
            $request->inputSet('field','created_at');
            $request->inputSet('order','desc');
        }
        if(!empty($request->input('ids'))){
            $request->inputSet('id',['in',$request->input('ids')]);
        }

        $request->inputSet('isdel','0');
        $result = parent::select($request);
        return $result;
    }

    public function deletecos(Request $request): Response
    {
        $cos_model = new MaterialDataCosModel();
        $row = $cos_model->select('key', 'material_data_id', 'material_path', 'catid')->where('id', $request->input('id'))->first();

        if(!empty($row['key'])){
            $key = urldecode($row['key']);
            $result = TencentCos::getInstance()->deleteBucketObject($key);

            $data['material_data_id'] = $row['material_data_id'];
            $data['material_path'] = $row['material_path'];
            $data['catid'] = $row['catid'];
            $this->sysncAllMaterialAction($data);

            return $this->json(0,'ok',$result);
        }else{
            return $this->json(500,'error',[]);
        }
    }
}